home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / pagedem.com / PAGEDEMO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  6.6 KB  |  135 lines

  1. /*                                                                           */
  2. /*                           PAGEDEMO.C                                      */
  3. /*                                                                           */
  4. /*   There is a nonstandard 320x400 256 color VGA mode which has two pages.  */
  5. /*   This program demonstrates its use by setting up the mode, drawing to    */
  6. /*   the two pages, and flipping the pages for instanteous appearance of     */
  7. /*   of the graphics.                                                        */
  8. /*                                                                           */
  9. /*   A scanline function is included which shows how to take advantage of    */
  10. /*   memory plane masking to draw four pixels simutaneously.                 */
  11. /*                                                                           */
  12. /*   The mode setting routine is based upon Michael Abrash's demo which      */
  13. /*   can be found in PJ71.ARC in LDOS/lib 10.                                */
  14. /*                                                                           */
  15. /*   Thanks to Lawrence Gozum, Paul Lefevre, Joseph Wofford, Dave Angel,     */
  16. /*   Neil Rubenking, Brian Buck, and Eric Ace for their patience and help.   */
  17. /*                                                                           */
  18. /*   Written for Turbo C. Compile with:  tcc pagedemo                        */
  19. /*                                                                           */
  20. /*   Copyright Gary Boone 1991. Free for use in Free/Share/Comm. programs.   */
  21. /*                                                                           */
  22. /*   Enjoy!                                                                  */
  23. /*                Gary Boone     CIS:73040,3725        --   23 April 1991    */
  24. /*                                                                           */
  25. #include    "dos.h"                  /* for getch() */
  26.  
  27. void switchModes(int mode);
  28. void clearScreen(int page);
  29. void scanline(int page, int x1, int x2, int y, int color);
  30.  
  31.  
  32. void main(void)
  33. {   int i,p,j;
  34.  
  35.     switchModes(0x13);
  36.     for (i=0;i<400;i++)                  /* Draw a pattern on page 0    */
  37.         scanline(0,0,i%320,i,i%256);     /* while we watch.             */
  38.  
  39.     for (i=0;i<400;i++)                  /* Draw another pattern on the */
  40.         scanline(1,i%320,319,i,i%256);   /* hidden page.                */
  41.  
  42.     getch();                             /* Wait for any key to be hit. */
  43.     outport(0x3D4, 0x800C);              /* Flip to other page,         */
  44.     getch();                             /* and wait.                   */
  45.  
  46.     p=0;                                 /* For fun, flip the pages     */
  47.     outportb(0x3D4, 0x0C);               /* quickly.                    */
  48.     for (i=0;i<500;i++)
  49.     {    outportb(0x3D5, 0x80*(p=1-p));
  50.          for(j=1;j<1000;j++);            /* delay so you can see the page */
  51.     }
  52.     getch();
  53.     switchModes(3);                       /* Done. Back to text mode.    */
  54. }
  55.  
  56.  
  57. void clearScreen(int page)    /* how to quickly fill the screen with a color */
  58. {   char far *addr;
  59.     unsigned int i;
  60.  
  61.     addr = (char far*) (0xA0000000+0x8000000*page);  /* point into video mem */
  62.     outport(0x3C4,0x0f02);                           /* set all planes on    */
  63.     for (i=0;i<0x8000;i++)
  64.         *(addr++)=(char) 0;                          /* four pixels at once! */
  65.  
  66. }
  67.  
  68. /* Scanline():   Draws horizontal lines quickly.                             */
  69. /*                 To increase speed, masks are determined from a look-up    */
  70. /*               table and written four at once, instead of being calculated */
  71. /*               one at a time. Further, the middle pixels are masked and    */
  72. /*               written four at a time. (In this mode, there are four pixels*/
  73. /*               at each address, one per plane. To pick one of the four, or */
  74. /*               any combination, just set the plane mask accordingly.)      */
  75. /*                 Note that if the pixels are (in order) a,b,c,d, then the  */
  76. /*               individual masks would be 0001b, 0010b, 0100b, and 1000b.   */
  77. /*                                                                           */
  78. void scanline(int page, int x1, int x2, int y, int color)
  79. {   char far *addr;
  80.     int  plane,i,i2;
  81.     char masks[]={1,3,7,15,2,6,14,14,4,12,12,12,8,8,8,8};
  82.  
  83.     addr = (char far*) (0xA0000000+0x8000000*page);
  84.     addr+=320/4*y+x1/4;  /* order matters! y*320/4 will wrap when y*320  */
  85.                          /*                 overflows the word length!   */
  86.     outportb(0x3C4, 2);  /* point Sequence Controller to Map Mask reg.   */
  87.  
  88.     /* first four pixels */
  89.     i2=x2-x1;                   /* figure number of pixels after first   */
  90.     if (x2-x1>3) i2=3;          /* but limit to first 4 pixels           */
  91.     plane=masks[(x1%4)*4+i2];   /* table is (x,y): x=start pix, y=length */
  92.     outportb(0x3C5,plane);      /* set the planes */
  93.     *(addr++)=(char) color;     /* draw! (then increment mem. pointer.)  */
  94.  
  95.     /* middle four-byte groups */
  96.     outportb(0x3C5,0xf);            /* set all four planes */
  97.     if ((x2-x1)/4>1)            /* if there are middle 4 byte groups...  */
  98.         for (i=x1/4+1; i<x2/4; i++)    /* draw all of 'em  */
  99.             *(addr++)=(char) color;
  100.  
  101.     /* do last four pixels */
  102.     if (x1/4 != x2/4)           /* if there is a last 4 byte group... */
  103.     {   plane=masks[x2%4];      /* obviously it starts at pixel 0...  */
  104.         outportb(0x3C5,plane);
  105.         *(addr++)=(char) color;
  106.     }
  107.  
  108. }
  109.  
  110.  
  111.  
  112.  
  113. void switchModes(int mode)       /* set mode including extended mode 13x    */
  114. {   unsigned int i, far *addr;
  115.     union REGS regs;
  116.  
  117.     regs.x.ax = mode;            /* normal mode set for all modes */
  118.     int86(0x10, ®s, ®s);
  119.  
  120.     if (mode==0x13)              /* modify mode 13 to get 320x400 */
  121.     {   outport(0x3C4, 0x0604);  /* Seq. Cont. turn off Chain 4 and odd/even */
  122.         outport(0x3CE, 0x4005);  /* Gr. Cont.: turn off odd/even */
  123.         outport(0x3CE, 0x0106);  /*            turn off chain    */
  124.         outport(0x3C4, 0x0F02);  /* enable all planes */
  125.         addr = (unsigned int far*) 0xA0000000;    /* points to words so   */
  126.         for (i=0; i < 0x8000; i++) *addr++ = 0;   /* erases both pages... */
  127.         outport(0x3D4, 0x0009);  /* CRTC: set max. scan line to 0         */
  128.         outport(0x3D4, 0x2014);  /*   set normal word addressing          */
  129.         outport(0x3D4, 0xE317);  /*       turn on byte mode               */
  130.     }
  131.  
  132. }
  133.  
  134.  
  135.